home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Modules
/
BackSpaceModules
/
Source
/
CreepyFace
/
CFWireFrame.m
< prev
next >
Wrap
Text File
|
1994-03-23
|
11KB
|
482 lines
#import "CFWireFrame.h"
@implementation CFWireFrame:Object
// this code is copyright Darcy Brockbank, 1993
//
// You may freely reuse and distribute this code in any way shape or
// form, provided that this notice stays intact.
//
// darcy@hasc.ca, samurai@cs.mcgill.ca
//
// StefView was implemented out of WorldSpaceView and retains some of the
// movement properties...
//
// The code for WorldSpaceView was written by Sam Streeper at CreepyFace, I think,
// and there were two other contributors, but I can't find their names in the
// source for it.
//
// CreepyFaceView shows a simple (ha!) spinning CreepyFace logo, in full 3D. The 3D code
// came from an app I wrote a long time ago called "CFWireFrame", and so the code
// is pretty scary. As well, this thing is only a quick hack, though a nice one.
//
// This thing has room for improvement, and if you do so, send me a copy!
//
// - darcy
#define SCALE 1.0045
- getCentre:(float*) x:(float *)y :(float *)z
{
*x=myCentre.x;
*y=myCentre.y;
*z=myCentre.z;
return self;
}
- getFrameColour:(float *)r :(float *)g :(float *)b
{
*r=myFrameColour.red;
*b=myFrameColour.blue;
*g=myFrameColour.green;
return self;
}
- getTagColour:(float *)r :(float *)g :(float *)b
{
*r=myTagColour.red;
*b=myTagColour.blue;
*g=myTagColour.green;
return self;
}
static int count(const char *s,char thisChar)
{
int c=0;
for (;*s!=(char)0;s++) if (*s==thisChar) c++;
return (c);
}
#define LIM 6400000.0
- init
{
[super init];
myLineWidth=0.1;
psint=sin(0.085);
nsint=-psint;
cost=cos(0.085);
bbox[0]=-LIM;
bbox[1]=-LIM;
bbox[2]=2*LIM;
bbox[3]=2*LIM;
myTable = [[NXStringTable alloc] init];
dimension=4;
return self;
}
- free
{
[myTable free];
return [super free];
}
- addMyPS:(char)command
{
myPSCommands[numberOfMyPS++]=command;
return self;
}
- addPoint:(float)x :(float)y :(float)z
{
myCoords[numberOfCoords*4]=x;
myCoords[numberOfCoords*4+1]=y;
myCoords[numberOfCoords*4+2]=z;
myCoords[numberOfCoords*4+3]=1.0;
numberOfCoords++;
return self;
}
- moveTo:(float)x:(float)y:(float)z
{
int i;
for(i=0;i<numberOfCoords*dimension;i+=dimension){
myCoords[i]+=(x-myCentre.x);
myCoords[i+1]+=(y-myCentre.y);
myCoords[i+2]+=(z-myCentre.z);
}
for(i=0;i<numberOfTags*coordsInATag*dimension;i+=dimension){
myTags[i]+=(x-myCentre.x);
myTags[i+1]+=(y-myCentre.y);
myTags[i+2]+=(z-myCentre.z);
}
myCentre.x=x;
myCentre.y=y;
myCentre.z=z;
return self;
}
- drawYourself:(float)zoom centeredOn:(float)X :(float)Y;
{
int i,j,x;
int stop,start;
BOOL behindMe;
DPSUserPathAction op;
behindMe=NO;
stop=numberOfCoords*dimension;
for (i=0,j=0;i<stop;j+=2,i+=dimension){
if (myCoords[i+2]>=-0.001) {
behindMe=YES;
break;
}
output[j]=((myCoords[i])*(-zoom/myCoords[i+2]))+X;
output[j+1]=((myCoords[i+1])*(-zoom/myCoords[i+2]))+Y;
}
if (!behindMe && stop!=0 && numberOfCoords>0){
PSsetrgbcolor(myFrameColour.red,myFrameColour.green,myFrameColour.blue);
DPSDoUserPath(output,2*numberOfCoords,dps_float,myPSCommands,
numberOfMyPS,bbox,dps_ustroke);
}
if (numberOfTags){
op=dps_ufill;
for(x=0;x<numberOfTags;x++){
behindMe=NO;
start=x*coordsInATag*dimension;
if (!(myTags[2+start]>=myCentre.z)) { // closer than centre
op = dps_ustroke;
}
stop=start+(coordsInATag*dimension);
for(j=0,i=start;i<stop;j+=2,i+=dimension){
if (myTags[i+2]>=0){
behindMe=YES;
break;
}
output[j]=((myTags[i])*(-zoom/myTags[i+2]))+X;
output[j+1]=((myTags[i+1])*(-zoom/myTags[i+2]))+Y;
}
if (!behindMe && coordsInATag > 0){
PSsetrgbcolor(myTagColour.red,myTagColour.green,myTagColour.blue) ;
DPSDoUserPath(output,(2*coordsInATag),dps_float,myTagPSCommands,
numberOfTagPS,bbox,op);
}
}
}
return self;
}
- rotate: (Direction) direction aroundAxis:(Axis) thisAxis atOrigin:(Origin) thisOrigin
{
double mysint;
double s1,s2,s3;
Origin origin;
int i;
if (direction==negative) {
mysint=nsint;
}
else {
mysint=psint;
}
origin=thisOrigin;
switch(thisAxis){
case x:
for (i=0;i<numberOfCoords*dimension;i+=dimension){
s2=myCoords[i+1]-origin.y;
s3=myCoords[i+2]-origin.z;
myCoords[i+1]=(float)((s2)*cost-(s3)*mysint)+origin.y;
myCoords[i+2]=(float)((s2)*mysint+(s3)*cost)+origin.z;
}
for (i=0; i<(numberOfTags*coordsInATag)*dimension; i+=dimension){
s2=myTags[i+1]-origin.y;
s3=myTags[i+2]-origin.z;
myTags[i+1]=(float)((s2)*cost-(s3)*mysint)+origin.y;
myTags[i+2]=(float)((s2)*mysint+(s3)*cost)+origin.z;
}
s2=myCentre.y-origin.y;
s3=myCentre.z-origin.z;
myCentre.y=(float)(s2*cost-s3*mysint)+origin.y;
myCentre.z=(float)(s2*mysint+s3*cost)+origin.z;
break;
case y:
for (i=0; i<numberOfCoords*dimension; i+=dimension){
s1=myCoords[i]-origin.x;
s3=myCoords[i+2]-origin.z;
myCoords[i]=(float)((s1)*cost+s3*mysint)+origin.x;
myCoords[i+2]=(float)((-s1)*mysint+s3*cost)+origin.z;
}
for (i=0; i<(numberOfTags*coordsInATag*dimension); i+=dimension){
s1=myTags[i]-origin.x;
s3=myTags[i+2]-origin.z;
myTags[i]=(float)((s1)*cost+s3*mysint)+origin.x;
myTags[i+2]=(float)((-s1)*mysint+s3*cost)+origin.z;
}
s1=myCentre.x-origin.x;
s3=myCentre.z-origin.z;
myCentre.x=(float)(s1*cost+s3*mysint)+origin.x;
myCentre.z=(float)(-s1*mysint+s3*cost)+origin.z;
break;
case z:
for (i=0; i<numberOfCoords*dimension; i+=dimension){
s1=myCoords[i]-origin.x;
s2=myCoords[i+1]-origin.y;
myCoords[i]=(float)(s1*cost-s2*mysint)+origin.x;
myCoords[i+1]=(float)(s1*mysint+s2*cost)+origin.y;
}
for (i=0; i<(numberOfTags*coordsInATag*dimension); i+=dimension){
s1=myTags[i]-origin.x;
s2=myTags[i+1]-origin.y;
myTags[i]=(float)(s1*cost-s2*mysint)+origin.x;
myTags[i+1]=(float)(s1*mysint+s2*cost)+origin.y;
}
s2=myCentre.y-origin.x;
s1=myCentre.x-origin.y;
myCentre.x=(float)(s1*cost-s2*mysint)+origin.x;
myCentre.y=(float)(s1*mysint+s2*cost)+origin.y;
}
return self;
}
- translate: (Direction) direction alongAxis: (Axis) thisAxis atRate:(float) rate
{
float mydir;
int i;
if(direction==negative) {
mydir=-1*rate;
}
else {
mydir=rate;
}
switch(thisAxis) {
case x:
myCentre.x+=mydir;
break;
case y:
myCentre.y+=mydir;
break;
case z:
myCentre.z+=mydir;
break;
}
for(i=0;i<numberOfCoords*dimension;i+=dimension){
myCoords[i+thisAxis]+=mydir;
}
for(i=0;i<numberOfTags*coordsInATag*dimension;i+=dimension){
myTags[i+thisAxis]+=mydir;
}
return self;
}
- setCentre:(float) x :(float)y :(float)z
{
printf("Setting\n");
myCentre.x=x;
myCentre.y=y;
myCentre.z=z;
return self;
}
- setFrameColour:(float) r :(float)g :(float)b
{
myFrameColour.red=r;
myFrameColour.green=g;
myFrameColour.blue=b;
return self;
}
- setTagColour:(float) r :(float)g :(float)b
{
myTagColour.red=r;
myTagColour.green=g;
myTagColour.blue=b;
return self;
}
- setNumberOfTags:(int)count
{
numberOfTags=count;
return self;
}
- setCoordsInATag:(int)count;
{
coordsInATag=count;
return self;
}
- setNumberOfTagPS:(int)count;
{
numberOfTagPS=count;
return self;
}
- setNumberOfCoords:(int) count;
{
numberOfCoords=count;
return self;
}
- setNumberOfMyPS:(int) count;
{
numberOfMyPS=count;
return self;
}
- setBoundingBox:(float *) thisBox
{
bbox[0]=-1.0e16;
bbox[1]=-1.0e16;
bbox[2]=1.0e16;
bbox[3]=1.0e16;
return self;
}
- (int) getNumberOfMyPS
{
return numberOfMyPS;
}
- (int) getNumberOfPoints
{
return (numberOfCoords);
}
- makeCFWireFrame:(const char *)thisFrame
{
const char *frameCoords,*framePS,*tagCoords,*numOfTags,*frameColour,
*frameCentre,*tagColour,*tagPS, *coordsInTag,*check;
int i;
char ps=0;
if ([myTable readFromFile:thisFrame]==nil){
return self;
NXRunAlertPanel(thisFrame,"The file is not in the given directory. Please fix this problem and restart the application.","Quit",NULL,NULL);
[NXApp terminate:self];
}
frameCoords=[myTable valueForStringKey:"FramePoints"];
tagCoords=[myTable valueForStringKey:"TagPoints"];
frameColour=[myTable valueForStringKey:"FrameColor"];
tagColour=[myTable valueForStringKey:"TagColor"];
framePS=[myTable valueForStringKey:"FramePS"];
coordsInTag=[myTable valueForStringKey:"PointsPerTag"];
numOfTags=[myTable valueForStringKey:"NumberOfTags"];
frameCentre=[myTable valueForStringKey:"FrameCenter"];
tagPS=[myTable valueForStringKey:"TagPS"];
numberOfTags=atoi(numOfTags);
coordsInATag=atoi(coordsInTag);
numberOfCoords=count(frameCoords,',')+1;
numberOfMyPS=count(framePS,',')+1;
numberOfTagPS=count(tagPS,',')+1;
sscanf(frameColour,"%f , %f , %f",
&myFrameColour.red,&myFrameColour.green,&myFrameColour.blue);
sscanf(tagColour,"%f , %f , %f",
&myTagColour.red,&myTagColour.green,&myTagColour.blue);
sscanf(frameCentre,"%f , %f , %f",&myCentre.x,&myCentre.y,&myCentre.z);
for(i=0,check=framePS;check!=(char *)1;i++,check=index(check,',')+1){
switch(check[0]){
case 'a':
switch (check[3]){
case 'n': ps=dps_arcn; break;
case 't': ps=dps_arct; break;
default: ps=dps_arc;
}
break;
case 'm': ps=dps_moveto;break;
case 'r':
switch(check[1]){
case 'm': ps=dps_rmoveto;break;
case 'l': ps=dps_rlineto; break;
default: ps=dps_rcurveto;
}
break;
switch(check[1]){
case 'l' :ps=dps_closepath; break;
case 'u':ps=dps_curveto; break;
}
case 'c':
switch(check[1]){
case 'l' :ps=dps_closepath; break;
case 'u':ps=dps_curveto; break;
}
break;
case 'u': ps=dps_ucache; break;
case 'l' : ps=dps_lineto; break;
default: ps=-1;
}
myPSCommands[i]=ps;
}
for(i=0,check=tagPS;check!=(char *)1;i++,check=index(check,',')+1){
switch(check[0]){
case 'a':
switch (check[3]){
case 'n': ps=dps_arcn; break;
case 't': ps=dps_arct; break;
default: ps=dps_arc;
}
break;
case 'm': ps=dps_moveto; break;
case 'r':
switch(check[1]){
case 'm': ps=dps_rmoveto; break;
case 'l': ps=dps_rlineto; break;
default: ps=dps_rcurveto;
}
break;
case 'c':
switch(check[1]){
case 'l' :ps=dps_closepath; break;
case 'u':ps=dps_curveto; break;
}
break;
case 'u': ps=dps_ucache; break;
case 'l' : ps=dps_lineto; break;
default: ps=-1; break;
}
myTagPSCommands[i]=ps;
}
for (i=0,check=frameCoords;i<numberOfCoords;i++,check=(index(check,',')+1)){
sscanf(check," %f",(&myCoords[i]));
}
for (i=0,check=tagCoords;i<numberOfTags*coordsInATag*4;i++,check=(index(check,',')+1)){
sscanf(check," %f",(&myTags[i]));
}
numberOfCoords/=4;
return self;
}
- readBinaryCodeFrom: (char *) thisFile
{
return self;
}
@end